package zsc.ruanc.practicaltraining.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import zsc.ruanc.practicaltraining.exception.ApiException;
import zsc.ruanc.practicaltraining.model.domain.TUser;
import zsc.ruanc.practicaltraining.model.domain.updatePasswordVo;
import zsc.ruanc.practicaltraining.model.result.JsonResult;

import zsc.ruanc.practicaltraining.model.vo.*;

import zsc.ruanc.practicaltraining.service.RabbitMQService;
import zsc.ruanc.practicaltraining.service.RedisService;
import zsc.ruanc.practicaltraining.service.UserService;
import zsc.ruanc.practicaltraining.utils.DataVerificationUtils;
import zsc.ruanc.practicaltraining.utils.PrintfUtils;
import zsc.ruanc.practicaltraining.utils.ResultUtils;

import javax.servlet.http.HttpServletRequest;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;


/**
 * 用户控制器
 */
@RestController
@RequestMapping("/user")
@Validated
@Api(tags = "用户模块/对于用户表的所有操作")
@Slf4j
public class UserController {

    @Autowired
    private RedisService redisService;

    @Autowired
    private UserService userService;

    @Autowired
    private RabbitMQService rabbitMQService;



    /**
     * 新建账号
     * @param createUserVo
     * @return
     */
    @PostMapping("/create")
    @ApiOperation(value = "创建新用户", httpMethod = "POST")
    public JsonResult createUser(@Validated @RequestBody createUserVo createUserVo) {

        PrintfUtils.print(createUserVo); // 打印请求信息

        // 验证code是否正确
        redisService.verificationCode(createUserVo.getEmail(), createUserVo.getCode());
        int userId = userService.createUser(createUserVo);
        // 删除验证码
        redisService.delete(createUserVo.getEmail());

        rabbitMQService.adminMailbox(userId, "欢迎使用我们的博客");

        return ResultUtils.success(true, "用户创建成功");
    }

    /**
     * 2.找回密码
     * @param findPasswordVo
     * @return
     */
    @PostMapping("/findPassword")
    @ApiOperation(value = "找回密码", httpMethod = "POST")
    public JsonResult sendFindPasswordCode(@Validated @RequestBody findPasswordVo findPasswordVo) {

        PrintfUtils.print(findPasswordVo); // 打印请求信息

        // 验证code是否正确
        redisService.verificationCode(findPasswordVo.getEmail(), findPasswordVo.getCode());

        userService.updatePassword(findPasswordVo.getEmail(), findPasswordVo.getPassword());
        // 删除验证码
        redisService.delete(findPasswordVo.getEmail());
        return ResultUtils.success(true, "密码修改成功");
    }

    /**
     * 修改密码
     * @param updatePasswordVo
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/updatePassword")
    @ApiOperation(value = "修改密码", httpMethod = "POST")
    public JsonResult updatePassword(@Validated @RequestBody updatePasswordVo updatePasswordVo, HttpServletRequest httpServletRequest) {

        PrintfUtils.print(updatePasswordVo); // 打印请求信息


        int id = (int)httpServletRequest.getAttribute("id");
        userService.updatePassword(id, updatePasswordVo.getOldPassword(), updatePasswordVo.getNewPassword());
        return ResultUtils.success(null, "密码修改成功,请重新登录");
    }

    /**
     * 修改用户名
     * @param name
     * @param httpServletRequest
     * @return
     */
    @GetMapping("/updateName/{name}")
    @ApiOperation(value = "修改用户名", httpMethod = "GET")
    @ApiImplicitParam(name = "name", value = "用户名", dataType = "String", paramType = "path")
    public JsonResult updateName(@NotBlank(message = "不能为空") @PathVariable("name") String name, HttpServletRequest httpServletRequest) {
        int id = (int)httpServletRequest.getAttribute("id");
        userService.updateName(id, name);
        return ResultUtils.success(null, "用户名修改成功");
    }

    /**
     * 修改用户头像
     * @param file
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/updateHead")
    @ApiOperation(value = "修改头像", httpMethod = "POST")
    public JsonResult updateHead(MultipartFile file, HttpServletRequest httpServletRequest) {
        int id = (int)httpServletRequest.getAttribute("id");
        userService.updateHead(id, file);
        return ResultUtils.success(null, "用户头像修改成功");
    }

    /**
     * 修改用户信息
     * @param userVo
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/updateInfo")
    @ApiOperation(value = "修改个人信息", httpMethod = "POST")
    public JsonResult updateInfo(@Validated @RequestBody UserVo userVo, HttpServletRequest httpServletRequest) {

        PrintfUtils.print(userVo); // 打印请求信息


        int id = (int)httpServletRequest.getAttribute("id");
        userVo.setId(id);
        userService.updateInfo(userVo);
        return ResultUtils.success(null, "信息修改成功");
    }

    @PostMapping("/updateEmail")
    @ApiOperation(value = "修改邮箱", httpMethod = "POST")
    public JsonResult updateEmail(@Validated @RequestBody emailVo emailVo, HttpServletRequest httpServletRequest) {

        PrintfUtils.print(emailVo); // 打印请求信息


        DataVerificationUtils.isCode(emailVo.getCode()); // 校验验证码
        int id = (int)httpServletRequest.getAttribute("id");
        redisService.verificationCode(emailVo.getEmail(), emailVo.getCode()); // 验证码是否正确
        userService.updateEmail(id, emailVo.getEmail());
        redisService.delete(emailVo.getEmail()); // 删除验证码
        return ResultUtils.success(null, "邮箱修改成功");
    }

    /**
     * 获得用户信息
     * @param httpServletRequest
     * @return
     */
    @GetMapping("/getUser")
    @ApiOperation(value = "获得个人信息", httpMethod = "GET")
    public JsonResult getUser(HttpServletRequest httpServletRequest) {
        int id = (int)httpServletRequest.getAttribute("id");
        return ResultUtils.success(userService.getUser(id));
    }

    @GetMapping("/getInfo")
    @ApiOperation(value = "一个用户查询另一个用户", httpMethod = "GET")
    public JsonResult getInfo(@NotBlank(message = "查询不能为空") @RequestParam(value = "name", required = false) String name) {
        return ResultUtils.success(userService.getUserInfo(name));
    }


    //---------------管理员权限--------------------------------------------------

    @GetMapping("/select")
    @ApiOperation(value = "获得用户消息(管理员权限)(精准查询)", httpMethod = "GET")
    public JsonResult select(@Min(message = "参数不能小于1", value = 1) @RequestParam(value = "id", required = false) Integer id,
                             @RequestParam(value = "email", required = false) String email) {

        if (id == null && email == null) {
            throw new ApiException(400);
        }


        TUser user = userService.select(id, email);
        if (user == null) {
            return ResultUtils.error(404, "没有该用户");
        }
        return ResultUtils.success(user);

    }

    @GetMapping("/setValid/{id}")
    @ApiOperation(value = "封号|解封(管理员权限)", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "目标用户id", dataType = "Integer", paramType = "path"),
            @ApiImplicitParam(name = "flag", value = "状态", dataType = "Boolean", paramType = "query")
    })
    public JsonResult setValid(@Min(message = "id不能小于1", value = 1) @PathVariable("id") Integer id,
                               @NotNull(message = "状态不能为空") @RequestParam("flag") Boolean flag) {
        return ResultUtils.success(userService.setValid(id, flag));
    }

    @GetMapping("/page")
    @ApiOperation(value = "获得用户消息(分页|管理员权限)(text有值就模糊查询，为null就查询全部)", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cur", value = "当前页", dataType = "Integer", paramType = "query", defaultValue = "1"),
            @ApiImplicitParam(name = "size", value = "页大小", dataType = "Integer", paramType = "query", defaultValue = "10"),
            @ApiImplicitParam(name = "text", value = "条件", dataType = "String", paramType = "query")
    })
    public JsonResult selectPage(@Min(message = "参数cur不能小于0", value = 0) @RequestParam(value = "cur", defaultValue = "1") Integer cur,
                                 @Min(message = "参数size不能小于1", value = 1) @RequestParam(value = "size", defaultValue = "10") Integer size,
                                 @RequestParam(value = "text", required = false) String text) {
        return ResultUtils.success(userService.selectPage(cur, size, text));
    }

    @GetMapping("/updateRole")
    @ApiOperation(value = "修改用户身份（管理员）", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "目标用户", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "role", value = "角色id", dataType = "Integer", paramType = "query")
    })
    public JsonResult updateRole(@Min(message = "参数id不能小于0", value = 1) @RequestParam(value = "id", required = false) Integer id,
                                 @Min(message = "参数role不能小于1", value = 1) @Max(message = "role不能大于2", value = 2) @RequestParam(value = "role", required = false) Integer role) {
        return ResultUtils.success(userService.updateRole(id, role), "身份修改成功");

    }

}
